home *** CD-ROM | disk | FTP | other *** search
/ Aminet 2 / Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso / Aminet / gfx / opal / lsidocs.lha / Source / Loaders / Rendition.c < prev    next >
C/C++ Source or Header  |  1993-04-25  |  8KB  |  318 lines

  1. /*  Rendition.c           by Martin Boyd 25-Apr-93.
  2.  *
  3.  *  An example file loader using the OpalVision LSI interface.
  4.  *
  5.  *  The rendition file format simply consists of a 1024 byte
  6.  * header (Described below) followed by 32 bit (RGBA) image data
  7.  * compressed using run-length encoding. Each run is encoded as
  8.  * 6 bytes:
  9.  *
  10.  *    Byte 0 - Red
  11.  *    Byte 1 - Green
  12.  *    Byte 2 - Blue
  13.  *    Byte 3 - Alpha
  14.  *    Byte 4 - Run length low byte
  15.  *    Byte 5 - Run length high byte
  16.  *
  17.  * NOTE: This loader only loads the 6RN format as described
  18.  *      above.
  19.  */
  20.  
  21.  
  22. #include <exec/types.h>
  23. #include <exec/memory.h>
  24. #include <libraries/dos.h>
  25. #include <proto/exec.h>
  26. #include <proto/dos.h>
  27. #include <opal/loadsave.h>
  28. #include <opal/opalpaint.h>
  29. #include <opal/opallib.h>
  30. #include <stdlib.h>
  31. #include <string.h>
  32.  
  33.  
  34. char Version[] = "\0$VER: Rendition.Loader 1.0 (25.04.93)";
  35.  
  36.     /* Rendition format information */
  37.  
  38. struct Tile
  39.     { long Ptr;
  40.       long Length;
  41.     };
  42.  
  43. struct RendHeader        /* 1024 byte header          */
  44.     { long    Magic;        /* H_MAGIC              */ 
  45.       SHORT    Version;    /* 2                  */
  46.       char    Label[128];    /* ASCII Desciption          */
  47.       char    Date[26];    /* Date of image creation      */
  48.       SHORT    Height;        /* Pixel height of image      */
  49.       SHORT    Width;        /* Pixel width of image          */
  50.       SHORT    TileHeight;    /* Pixel height of tile          */
  51.       SHORT    TileWidth;    /* Pixel width of tile          */
  52.       SHORT    Format;        /* See below              */
  53.       SHORT    Encoding;    /* See below              */
  54.       long    NumRuns;    /* Number of runs          */
  55.       SHORT    BlockSize;    /* 1024                  */
  56.       SHORT XOffset;    /* Horizontal offset          */
  57.       SHORT YOffset;    /* Vertical offset          */
  58.       long CMapLen;        /* Number of colour table entries */
  59.       long CMapPtr;        /* Pointer to ColourMap          */
  60.       char CMapName[64];    /* Colour Map filename          */
  61.       struct Tile Tile[64];    /* Tile pointer table          */
  62.       char UnSpec[258];    /* Unspecified (reserved)      */
  63.     };
  64.  
  65.  
  66. #define H_MAGIC        0xE880
  67. #define H_BLOCKSIZE    1024
  68. #define H_HEADERSIZE    1024
  69.  
  70.     /* Format types */
  71. #define H_CRGBAPIX    2    /* 4 bytes per pixel    */
  72. #define H_6RUNLH    11    /* 6 bytes per run    */
  73. #define H_2RUN        12    /* 2 bytes per run; colour map in seperate file */
  74. #define H_2RUNMAP    13    /* 2 bytes per run; colour map in image file */
  75. #define H_COLOURMAP    20    /* 4 bytes per entry    */
  76. #define H_MIPMAP    22    /* Mip map: header, map table and 4-byte pixels */
  77. #define H_ONEDRGBA8    23    /* 1D table of 4-byte pixels */
  78. #define H_ONEDBYTE    24    /* 1D table of bytes */
  79.  
  80.  
  81. char LoaderName[] = "Rendition";
  82. char PortName[] = "Rendition_Loader";
  83.  
  84.  
  85. int Width,Height;        /* Dimension of the image being loaded    */
  86. BPTR File;            /* File handle of image being loaded    */
  87. ULONG LoadFlags;        /* Flags from the OVCMD_LOADIMAGE command */
  88. struct MsgPort *LoadPort;    /* This modules message port        */
  89. struct OpalBase *OpalBase;
  90.  
  91. BOOL Do_Load (void);
  92.  
  93.  
  94. void main (void)
  95. {
  96.    struct LSIMessage *Mesg;
  97.    struct RendHeader *Header;
  98.  
  99.     LoadPort = CreatePort (PortName,0);
  100.     if (LoadPort==NULL)
  101.         exit (10);
  102.     OpalBase = (struct OpalBase *)OpenLibrary ("opal.library",0);
  103.     if (OpalBase==NULL)
  104.         { DeletePort (LoadPort);
  105.           exit (10);
  106.         }
  107.  
  108.     if (!AddOVLoader (LoaderName,LoadPort,
  109.             OVLF_ALLOWIMAGE|OVLF_ALLOWALPHA|OVLF_NEEDFILENAME))
  110.         { DeletePort (LoadPort);
  111.           CloseLibrary ((struct Library *)OpalBase);
  112.           exit (10);
  113.         }
  114.     CloseLibrary ((struct Library *)OpalBase);    /* library must be closed */
  115.     OpalBase = NULL;
  116.  
  117.     while (1)
  118.         { WaitPort (LoadPort);
  119.           while (Mesg = (struct LSIMessage *)GetMsg (LoadPort))
  120.             { switch (Mesg->lsi_Type)
  121.                 { case OVCMD_LOADIMAGE:
  122.                     File = Mesg->lsi_File;
  123.                     LoadFlags = Mesg->lsi_Flags;
  124.                     ReplyMsg ((struct Message *)Mesg);
  125.                     Do_Load();
  126.                     break;
  127.                   case OVCMD_EXPUNGE:
  128.                     if (!OpalBase)
  129.                         OpalBase = (struct OpalBase *)
  130.                             OpenLibrary ("opal.library",0);
  131.                     RemOVLoader (LoaderName);
  132.                     if (OpalBase)
  133.                         CloseLibrary ((struct Library *)OpalBase);
  134.                     DeletePort (LoadPort);
  135.                     ReplyMsg ((struct Message *)Mesg);
  136.                     exit (0);
  137.                     break;
  138.                   case OVCMD_FORMATCHECK:
  139.                     Header = (struct RendHeader *)Mesg->lsi_Address;
  140.                     if ((Header->Magic!=H_MAGIC) ||
  141.                         (Header->Format!=H_6RUNLH))
  142.                         Mesg->lsi_Result = FALSE;
  143.                     else
  144.                         { Width = Header->Width;
  145.                           Height = Header->Height;
  146.                           Mesg->lsi_Result = TRUE;
  147.                           Mesg->lsi_Width = Width;
  148.                           Mesg->lsi_Height = Height;
  149.                           Mesg->lsi_Depth = 24;
  150.                           Mesg->lsi_Flags = LSIF_HASIMAGE|LSIF_HASALPHA;
  151.                         }
  152.                     ReplyMsg ((struct Message *)Mesg);
  153.                     break;
  154.                 }
  155.             }
  156.         }
  157. }
  158.  
  159.  
  160.  
  161. BOOL Do_Load (void)
  162. {
  163.    int x,y;
  164.    struct MsgPort *HostPort;
  165.    struct LSIMessage Mesg;
  166.    UBYTE *RBuff,*GBuff,*BBuff,*ABuff,*DestBuff,*SrcBuff;
  167.    register UBYTE *Src,*R,*G,*B,*A,RData,GData,BData,AData;
  168.    long SBuffSize,DBuffSize,FileLength,RunLength,AmountLeft;
  169.    long AmountRead,FilePos;
  170.    int DBuffRows,Row;
  171.  
  172.  
  173.     HostPort = FindPort (OVLOADERPORT);    /* Find the host port */
  174.     if (HostPort==NULL) return (FALSE);
  175.  
  176.     memset (&Mesg,0,sizeof(struct LSIMessage));
  177.     Mesg.lsi_Node.mn_Node.ln_Type = NT_MESSAGE;
  178.     Mesg.lsi_Node.mn_ReplyPort = LoadPort;
  179.     Mesg.lsi_Node.mn_Length = sizeof (struct LSIMessage);
  180.  
  181.         /* This buffer is used to hold the decompressed data */
  182.     DBuffRows = 20;
  183.     do
  184.         { DBuffSize = DBuffRows * Width * 4;
  185.           DestBuff = AllocMem (DBuffSize,MEMF_CLEAR);
  186.           if (DestBuff==NULL)
  187.             DBuffRows--;
  188.         } while ((DestBuff==NULL) && (DBuffRows>0));
  189.  
  190.     if (DBuffRows==0)
  191.         { Mesg.lsi_Type = OVCMD_ERROR;
  192.           Mesg.lsi_Result = LSI_ERR_OUTOFMEM;
  193.           LSICmd (HostPort,LoadPort,&Mesg);
  194.           return (FALSE);
  195.         }
  196.     RBuff = DestBuff;
  197.     GBuff = DestBuff+(1*DBuffRows*Width);
  198.     BBuff = DestBuff+(2*DBuffRows*Width);
  199.     ABuff = DestBuff+(3*DBuffRows*Width);
  200.  
  201.         /* Allocate a buffer for raw file data.
  202.          * Allocate the biggest buffer we can, start
  203.          * with the size of the file and work our way down.
  204.          */
  205.     Seek (File,0,OFFSET_END);
  206.     FileLength = Seek (File,sizeof(struct RendHeader),OFFSET_BEGINNING);
  207.     SBuffSize = FileLength - sizeof (struct RendHeader);
  208.  
  209.     do
  210.         { SrcBuff = AllocMem (SBuffSize,MEMF_CLEAR);
  211.           if (SrcBuff==NULL)
  212.             SBuffSize = SBuffSize/2;
  213.         }
  214.     while ((SrcBuff==NULL) && (SBuffSize>(DBuffSize+1024)));
  215.  
  216.     if (SrcBuff==NULL)
  217.         { FreeMem (DestBuff,DBuffSize);
  218.           Mesg.lsi_Type = OVCMD_ERROR;
  219.           Mesg.lsi_Result = LSI_ERR_OUTOFMEM;
  220.           LSICmd (HostPort,LoadPort,&Mesg);
  221.           return (FALSE);
  222.         }
  223.  
  224.         /* Read in Image data and get the first run */
  225.     FilePos = Seek (File,0,OFFSET_CURRENT);
  226.     AmountRead = Read (File,SrcBuff,SBuffSize);
  227.     AmountLeft = AmountRead;
  228.     R = RBuff;
  229.     G = GBuff;
  230.     B = BBuff;
  231.     A = ABuff;
  232.     Src = SrcBuff;
  233.     RData = *Src++;
  234.     GData = *Src++;
  235.     BData = *Src++;
  236.     AData = *Src++;
  237.     RunLength = *Src++;
  238.     RunLength += (*Src++)<<8;
  239.     Row = 0;
  240.     AmountLeft -=6;
  241.  
  242.     for (y=0; y<Height; y++)
  243.         { for (x=0; x<Width;x++)
  244.             { if (RunLength==0)
  245.                 { if ((AmountLeft<6) && (FilePos+AmountRead<FileLength))
  246.                     { FilePos += AmountRead-AmountLeft;
  247.                       Seek (File,FilePos,OFFSET_BEGINNING);
  248.                       AmountRead = Read (File,SrcBuff,SBuffSize);
  249.                       AmountLeft = AmountRead;
  250.                       Src = SrcBuff;
  251.                     }
  252.                   RData = *Src++;
  253.                   GData = *Src++;
  254.                   BData = *Src++;
  255.                   AData = *Src++;
  256.                   RunLength = *Src++;
  257.                   RunLength += (*Src++)<<8;
  258.                   AmountLeft -= 6;
  259.                 }
  260.               *R++ = RData;
  261.               *G++ = GData;
  262.               *B++ = BData;
  263.               *A++ = AData;
  264.               RunLength--;
  265.             }
  266.           Row++;
  267.  
  268.             /* Once decompress buffer is full, send
  269.              * image data to host.
  270.              */
  271.  
  272.           if ((Row==DBuffRows) || (y==Height-1))
  273.             { Mesg.lsi_Planes[0] = RBuff;
  274.               Mesg.lsi_Planes[1] = GBuff;
  275.               Mesg.lsi_Planes[2] = BBuff;
  276.               Mesg.lsi_Width = Width;
  277.               Mesg.lsi_Height = Row;
  278.               Mesg.lsi_X = 0;
  279.               Mesg.lsi_Y = y-Row+1;
  280.               Mesg.lsi_Type = OVCMD_SENDDATA;
  281.               Mesg.lsi_SubType = OVDF_RGB;
  282.               LSICmd (HostPort,LoadPort,&Mesg);
  283.  
  284.                 /* Send Alpha channel data if requested */
  285.  
  286.               if (LoadFlags & LSIF_ALPHA)
  287.                 { Mesg.lsi_Planes[0] = ABuff;
  288.                   Mesg.lsi_Width = Width;
  289.                   Mesg.lsi_Height = Row;
  290.                   Mesg.lsi_X = 0;
  291.                   Mesg.lsi_Y = y-Row+1;
  292.                   Mesg.lsi_Type = OVCMD_SENDDATA;
  293.                   Mesg.lsi_SubType = OVDF_ALPHA;
  294.                   LSICmd (HostPort,LoadPort,&Mesg);
  295.                 }
  296.               Row = 0;
  297.               R = RBuff;
  298.               G = GBuff;
  299.               B = BBuff;
  300.               A = ABuff;
  301.             }
  302.  
  303.           if ((y & 0xF)==0)
  304.             { Mesg.lsi_Type = OVCMD_PERCENTAGE;
  305.               Mesg.lsi_Address = "Rend ";
  306.               Mesg.lsi_Result = (y*100)/Height;
  307.               LSICmd (HostPort,LoadPort,&Mesg);
  308.             }
  309.         }
  310.  
  311.     Mesg.lsi_Type = OVCMD_DONE;
  312.     LSICmd (HostPort,LoadPort,&Mesg);
  313.     FreeMem (DestBuff,DBuffSize);
  314.     FreeMem (SrcBuff,SBuffSize);
  315.     return (TRUE);
  316. }
  317.  
  318.